package cn.eric.game.swing.rpg;

import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

import javax.swing.ImageIcon;
import javax.swing.JPanel;

public class MyPanel2 extends JPanel implements KeyListener {
	
	private static final int WIDTH = 480;
	private static final int HEIGHT = 480;
	//设定背景方格默认行数
	private static final int ROW = 15; 
	//设定背景方格默认列数
	private static final int COL = 15;
	//单个图像大小，我默认采用 32x32 图形,可根据需要调整比例。 
	//当时，始终应和窗体大小比例协调;比如 32x32 的图片，如何 
	//一行设置 15 个，那么就是 480,也就是本例子默认的窗体大小， 
	//当然，我们也可以根据 ROW*CS,COl*CS 在初始化时自动调整 
	//窗体大小，以后的例子中会用到类似情况。总之一句话，编程 
	//是[为目的而存在的]，所有的方法，大家都可任意尝试和使用。
	private static final int CS = 32;
	//设定地图，通常在 rpg 类型游戏开发中，以[二维数组]对象为 
	//基础进行地图处理，用以描绘出 X 坐标和 Y 坐标。实际上,即令 
	//再华丽的 RPG 类游戏，都是从这些简单的 X,Y 坐标开始的。 
	//PS:所谓[数组]，大家可以简单的理解为即数据的集合，一维数组 
	//仅包含 X 轴，而二维是由 X,Y 两个轴组成的，X 与 Y 的交织点，即为 
	//一条数据。
	private int[][] map = {
			{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, 
			{0,1,1,1,1,1,1,1,1,1,1,1,1,1,0}, 
			{0,1,0,0,0,0,0,0,0,0,0,0,0,1,0}, 
			{0,1,0,0,0,0,0,0,0,0,0,0,0,1,0}, 
			{0,1,0,0,0,0,0,0,0,0,0,0,0,1,0}, 
			{0,1,0,0,0,0,0,0,0,0,0,0,0,1,0}, 
			{0,1,0,0,0,0,0,0,0,0,0,0,0,1,0}, 
			{0,1,0,0,0,0,0,0,0,0,0,0,0,1,0}, 
			{0,1,0,0,0,0,0,0,0,0,0,0,0,1,0}, 
			{0,1,0,0,0,0,0,0,0,0,0,0,0,1,0}, 
			{0,1,0,0,0,0,0,0,0,0,0,0,0,1,0}, 
			{0,1,0,0,0,0,0,0,0,0,0,0,0,1,0}, 
			{0,1,0,0,0,0,0,0,0,0,0,0,0,1,0}, 
			{0,1,1,1,1,1,1,1,1,1,1,1,1,1,0}, 
			{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
	// 设定显示图像对象
	private Image floorImage; 
	private Image wallImage;
	private Image roleImage;
	// 角色坐标
	private int x,y;
	
	public MyPanel2() {
		//设定初始构造时面板大小
		setPreferredSize(new Dimension(WIDTH, HEIGHT)); //于初始化时载入图形
		// 于初始化时载入图形
		loadImage();
		// 初始化角色所在的位置，由于本例行列皆为15，估 x 与 y 的极限数值也皆为 15
		//即由 15x15 的方格图像，组成了角色的可见活动区域。
		x = 8;
		y = 8;
		
		//设定焦点在本窗体并付与监听对象 
		setFocusable(true); 
		addKeyListener(this);
	}
	//描绘窗体，此处在默认 JPanel 基础上构建底层地图. 
	public void paintComponent(Graphics g) {
		super.paintComponent(g); //画出地图
		drawMap(g);
		drawRole(g);
	}
	
	/**
	* 载入图像 *
	*/
	private void loadImage() {
		//获得当前类对应的相对位置 image 文件夹下的地板图像[以下图像可用任意素材代替] 
		ImageIcon icon = new ImageIcon(getClass().getResource("image/greenback.jpg"));
		//将地板图像实例付与 floorImage
		floorImage = icon.getImage();
		//获得当前类对应的相对位置 image 文件夹下的墙体图像
		icon = new ImageIcon(getClass().getResource("image/castle01.png")); //将墙体图像实例付与 wallImage
		wallImage = icon.getImage();
		icon = new ImageIcon(getClass().getResource("image/Superhero01.png"));
		roleImage = icon.getImage();
	}
	
	private void drawRole(Graphics g) {
		//我加上这么一句，设置上[英雄]角色的位置;请注意，这个位置原来有块[地板]的。
		g.drawImage(roleImage, x*CS, y*CS,CS,CS, this);
	}
	
	private void drawMap(Graphics g) {
		//在 Java 或任何游戏开发中，算法都是最重要的一步，本例尽使用简单的双层 for 循环进行地图描绘，
		for (int x = 0; x < ROW; x++) {
			for (int j = 0; j < COL ; j++) {
				switch (map[x][j]) {
					case 0 : //map 的标记为 0 时画出地板,在指定位置[描绘]出我们所加载的图形，以下同 
						g.drawImage(floorImage, j * CS, x * CS,CS,CS, this); 
						break;
					case 1 :
						g.drawImage(wallImage, j * CS, x * CS,CS,CS, this);
						break;
					default: //当所有 case 值皆不匹配时，将执行此操作。
						break;
				}
			}
		}
	}
	@Override
	public void keyTyped(KeyEvent e) {
		// TODO Auto-generated method stub
		
	}
	@Override
	public void keyPressed(KeyEvent e) {
		//获得按键编号
		int keyCode = e.getKeyCode();
		//通过转换器匹配事件
		switch (keyCode) {
			//当触发 Left 时
			case KeyEvent.VK_LEFT :
				x--;
				break;
			//当触发 Right 时
			case KeyEvent.VK_RIGHT :
				// X++，即向右移动一方格 
				x++;
				break; 
			//当触发 Up 时
			case KeyEvent.VK_UP :
				// y--,即向上移动一方格 
				y--;
				break;
			//当触发 Down 时
			case KeyEvent.VK_DOWN :
				// y++,即向下移动一方格 
				y++;
				break;
		}
		repaint();
	}

	@Override
	public void keyReleased(KeyEvent e) {
		// TODO Auto-generated method stub
		
	}
}
